import { AxiosRequestConfig, AxiosPromise, AxiosResponse } from "../types"
import xhr from "./xhr"
import { buildURL, isAbsoluteURL, combineURL } from "../helpers/url"
import { flattenHeaders } from "../helpers/headers"
import transform from "./transform"

export default function dispatchRequest(config: AxiosRequestConfig): AxiosPromise {
  throwIfCancellationRequested(config)// 1. 检查是否有取消请求的信号
  processConfig(config) // 2. 预处理请求配置（重点！处理url、数据、请求头）
  return xhr(config).then((res) => {  // 发送 XHR 请求，返回原始响应
    return transformResponseData(res)  // 后处理响应数据，返回最终响应
  }, e => {
    if (e && e.response) {
      e.response = transformResponseData(e.response)
    }
    return Promise.reject(e)
  })

}
// 配置处理
function processConfig(config: AxiosRequestConfig): void {
  config.url = transformURL(config)  // URL 转换
  config.data = transform(config.data, config.headers, config.transformRequest)  // 请求数据转换
  config.headers = flattenHeaders(config.headers, config.method!)
}

export function transformURL(config: AxiosRequestConfig): string {
  let { url, params, paramsSerializer, baseURL } = config
  if (baseURL && isAbsoluteURL(url!)) {
    url = combineURL(baseURL, url)
  }
  return buildURL(url!, params, paramsSerializer)
}


function transformResponseData(res: AxiosResponse): AxiosResponse {
  res.data = transform(res.data, res.headers, res.config.transformResponse)
  return res
}

function throwIfCancellationRequested(config: AxiosRequestConfig): void {
  if (config.cancelToken) {
    config.cancelToken.throwIfRequested()
  }
}
